/****************************************************************************
 * taskapp
 * Tested MCU 
 * Owner : apleilx
 * **************************************************************************/
#define _TEMPLIB_MODULE_
#include "templib.h"

#ifndef INT16_MAX
#define INT16_MAX 0x7FFF
#endif
   
/*****************************************************************************//*!
*
* @brief   temperature calculate .
*          ad val to temperature       
* @param   none
*
* @return  none
*
* @ Pass/ Fail criteria: none
*****************************************************************************/
void TempCal(uint8_t Ch)
{
    float   Temp;
    float   CalData,Cal;       
//    int32_t CalInt32;
    int16_t CalInt;
    int16_t x0,x1,y0,y1;
    int8_t  Cnt;
    
    if(Ch >= TEMP_CH_AMOUNT)
        return ;
    
    //linear transformation                                                     //y = (x - ADL) * (DIV_H - DIV_L)/(ADH - ADL)
    Temp  = (TempADVal[Ch] - TempMarkTable[Ch].MarkADL)*( TEMP_DIVISION_MAX - TEMP_DIVISION_MIN );   
    Temp /= (TempMarkTable[Ch].MarkADH - TempMarkTable[Ch].MarkADL );
//    Temp      = CalInt32;
    //Non-linear correct with TempSensorTab                                     //y = (x-x0)*(y1-y0)/(x1-x0)
    CalData = TempSensorTab[0].Division;
    if( Temp < CalData  )
    {
        Temp = TempSensorTab[0].Temp;
        TempErrSt[Ch] |= TEMP_ERR_TABLE_L_MASK;
    }
    else
    {
        TempErrSt[Ch] &= (uint8_t)(~TEMP_ERR_TABLE_L_MASK);
        Cnt = 0;
        do{
            Cnt ++;
            CalData = TempSensorTab[Cnt].Division;
            CalInt  = TempSensorTab[Cnt].Division;
        }while( (CalData < Temp) && ( CalInt !=  INT16_MAX));
        
        if( INT16_MAX == CalInt )
        {
            Temp = TempSensorTab[Cnt-1].Temp;
            TempErrSt[Ch] |= TEMP_ERR_TABLE_H_MASK;
        }
        else
        {
            TempErrSt[Ch] &= ~TEMP_ERR_TABLE_H_MASK;
            x1 = TempSensorTab[Cnt].Division;
            y1 = TempSensorTab[Cnt].Temp;
            x0 = TempSensorTab[Cnt - 1].Division;
            y0 = TempSensorTab[Cnt - 1].Temp;
            
            Temp  = (Temp - x0) * (y1 - y0);                                    
            Temp /= (x1 - x0);
            Temp += y0;
        }
    }
    
    //user correct                                                              //y = ( 1 + pk/4000)*x + pb
    CalData = Temp;
    Temp *= TempCorrectTable[Ch].PK;
    Temp /= 4000;
    Temp += CalData;
    Temp += TempCorrectTable[Ch].PB;
    
	CalData = TempLimiteTable[Ch].LimiteL - 20;
	Cal     = TempLimiteTable[Ch].LimiteH + 20;
    if(Temp < CalData)
    {
        TempErrSt[Ch] |= (uint8_t)TEMP_ERR_LIMITE_L_MASK;
		Temp = CalData;
//        return;
    }
    else if(Temp > Cal)
    {
        TempErrSt[Ch] |= (uint8_t)TEMP_ERR_LIMITE_H_MASK;
		Temp = Cal;
//        return;
    }
    else
	{
        TempErrSt[Ch] &= ~(TEMP_ERR_LIMITE_L_MASK | TEMP_ERR_LIMITE_H_MASK);
	}
    
    //y = 0.7 * last + 0.3 * cur
     CalData = Temperature[Ch];
     Temp = CalData * 0.7 + Temp * 0.3;
     Temperature[Ch] = Temp;

	 CalData = TemperatureDisp[Ch];
	 Temp = CalData * 0.85 + Temp * 0.15;
	 TemperatureDisp[Ch] = Temp;  
}

/*****************************************************************************//*!
*
* @brief   get temperature .
*               
* @param   none
*
* @return  none
*
* @ Pass/ Fail criteria: none
*****************************************************************************/
int16_t TempGet(uint8_t Ch)
{
    if(Ch >= TEMP_CH_AMOUNT)
	{
        return INT16_MAX;
	}
    else
	{
	    if( Temperature[Ch] < 0)
	        return (int16_t)(Temperature[Ch] - 0.5);
        else
            return (int16_t)(Temperature[Ch] + 0.5);
	}
             
//    return  (int16_t)Temperature[Ch];
}

/*****************************************************************************//*!
*
* @brief   get temperature For display.
*               
* @param   none
*
* @return  none
*
* @ Pass/ Fail criteria: none
*****************************************************************************/
int16_t DispTempGet(uint8_t Ch)
{

    if(Ch >= TEMP_CH_AMOUNT)
	{
        return INT16_MAX;
	}
    else
	{
	    if( Temperature[Ch] < 0)
	        return (int16_t)(TemperatureDisp[Ch] - 0.5);
        else
            return (int16_t)(TemperatureDisp[Ch] + 0.5);
	}
             
//    return  (int16_t)TemperatureDisp[Ch];
}

/*****************************************************************************//*!
*
* @brief   set Ad val .
*               
* @param   none
*
* @return  none
*
* @ Pass/ Fail criteria: none
*****************************************************************************/
void TempADSet(uint8_t Ch ,int16_t AD_Val)
{
    if(Ch >= TEMP_CH_AMOUNT)
        return ;
    else
        TempADVal[Ch] = AD_Val;
}

/*****************************************************************************//*!
*
* @brief   Get error .
*                
* @param   none
*
* @return  none
*
* @ Pass/ Fail criteria: none
*****************************************************************************/
uint8_t TempErrGet(uint8_t Ch)
{
    if(Ch >= TEMP_CH_AMOUNT)
        return 0;
    else
        return TempErrSt[Ch];
}
